<?php
declare (strict_types=1);

namespace app\api\controller\v1;

use app\api\helpers\v1\traits\WeekDay;
use app\api\helpers\v1\WXBizDataCrypt;
use app\api\model\v1\Admins;
use app\api\model\v1\EnterUnit;
use app\api\model\v1\SystemConfig;
use app\api\model\v1\Users;
use app\api\validate\v1\LoginValidate;
use app\BaseController;
use Qcloud\Sms\SmsMultiSender;
use think\exception\ValidateException;
use think\facade\Config;
use think\Request;

class User extends BaseController
{
    use WeekDay;

    /**
     * @User: 刘海龙
     * @Date: 2021/9/3
     * @Time: 11:28
     * @return \think\response\Json
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     * 微信管理者登录
     */
    public function wxManagementLogin()
    {
        $data = $this->request->param();
        try {
            if ($data['type'] === Users::TYPE_ONE) {
                $this->validate(['mobile' => $data['mobile'], 'password' => $data['password']], LoginValidate::class);
                if (!$admin = Admins::where('mobile', $data['mobile'])->find()) {
                    return $this->response(403, '用户名不存在');
                }
                if (!password_verify($data['password'], $admin->password)) {
                    return $this->response(403, '密码错误');
                }
                $data['admin_id'] = $admin->id;
                $is_management = Users::IS_MANAGEMENT_ONE;
                $is_auth = $admin->enter_unit_id === 0 ? Users::IS_AUTH_ONE : Users::IS_AUTH_TWO;
                $unit_id = $admin->enter_unit_id;
            } else if ($data['type'] === Users::TYPE_TWO) {
                $is_management = Users::IS_MANAGEMENT_ZERO;
                $is_auth = Users::IS_AUTH_THREE;
                $unit_id = 0;
                //去除手机和密码的字段
                unset($data['mobile'], $data['password']);
            } else {
                return $this->response(500, '未找到相关信息');
            }
            $data['is_management'] = $is_management;
            $data['is_auth'] = $is_auth;
            $data['unit_id'] = $unit_id;
            //存在问题一旦退出登录后再次登录就找不到token 需处理
            $res = Users::find($this->request->wx_user_id);
            if (is_null($res)) {
                return $this->response(500, '未找到相关信息');
            }
           $user = $res->save($data);
            if ($user){
                $res = Users::with(['unit'])->find($this->request->wx_user_id);
                return $this->response($res->toArray());
            }else{
                return $this->response(403,"登录失败");
            }

        } catch (ValidateException $exception) {
            // 验证失败 输出错误信息
            return $this->response(403, $exception->getError());
        }
    }


    /**
     * @User: 刘海龙
     * @Date: 2021/9/3
     * @Time: 10:27
     * @return \think\response\Json
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     * 获取token
     */
    public function getToken()
    {
        $code = $this->request->param('code');
        $wx_url = "https://api.weixin.qq.com/sns/jscode2session?appid=" . Config::get('wechat.zfhf.app_id') . "&secret=" . Config::get('wechat.zfhf.app_secret') . "&js_code=" . $code . "&grant_type=" . Config::get('wechat.zfhf.grant_type') . "";
        $wx_data = $this->http($wx_url, 'get');
        if ($wx_data[0] == 200) {
            $wxResult = json_decode($wx_data[1], TRUE);
            //判空
            if (empty($wxResult)) {
                return $this->response(500, '获取session_key,openID时异常，微信内部错误');
            } else {
                //判断返回的结果中是否有错误码
                if (isset($wxResult['errcode'])) {
                    //如果有错误码，调用抛出错误方法
                    return $this->response(500, $wxResult);
                } else {
                    //1.通过openid 查看用户是否存在
                    $user = Users::where('openid', $wxResult['openid'])->find();
                    //2判断用户是否存在
                    if (!is_null($user)) {
                        $uid = $user['id'];
                    } else {
                        //如果为空 把openid数据库插入一条
                        $new_user_id = Users::create(['openid' => $wxResult['openid'], 'session_key' => $wxResult['session_key']])->id;
                        $uid = $new_user_id;
                    }
                }
            }
            $key = $this->token->createToken($uid);//生成token
            return $this->response(['token' => $key]);
        } else {
            return $this->response(500, '连接微信服务器失败');
        }
    }


    /**
     * @User: 刘海龙
     * @Date: 2021/9/3
     * @Time: 10:28
     * @return \think\response\Json
     * 验证token 返回 true 或 false
     */
    public function tokenVerify()
    {
        $token = $this->request->param('token');
        if (!$token) {
            return $this->response(500, 'token不允许为空');
        }
        $valid = $this->verifyToken($token);
        $arr = ['isValid' => $valid];
        return json($arr);
    }

    /**
     * @param $token
     * @User: 刘海龙
     * @Date: 2021/9/3
     * @Time: 10:28
     * @return bool
     * 验证Token
     */
    public function verifyToken($token)
    {
        $exist = $this->token->checkTokenJWT($token);
        if ($exist['code'] === 10000) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * @User: 刘海龙
     * @Date: 2021/9/3
     * @Time: 15:23
     * @return \think\response\Json
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     * 验证手机号并获取手机号
     */
    public function verifyMobile()
    {
        $data = $this->request->param();
        //解析手机号
        $appid = Config::get('wechat.zfhf.app_id');
        $code = $this->request->param('code');
        $wx_url = "https://api.weixin.qq.com/sns/jscode2session?appid=" . Config::get('wechat.zfhf.app_id') . "&secret=" . Config::get('wechat.zfhf.app_secret') . "&js_code=" . $code . "&grant_type=" . Config::get('wechat.zfhf.grant_type') . "";
        $wx_data = $this->http($wx_url, 'get');
        if ($wx_data[0] == 200) {
            $wxResult = json_decode($wx_data[1], TRUE);
            //判空
            if (empty($wxResult)) {
                return $this->response(500, '获取session_key,openID时异常，微信内部错误');
            } else {
                //判断返回的结果中是否有错误码
                if (isset($wxResult['errcode'])) {
                    //如果有错误码，调用抛出错误方法
                    return $this->response(500, $wxResult);
                } else {
                    //1.通过openid 查看用户是否存在
                  //  $user = Users::where('openid', $wxResult['openid'])->find();
                    $session_key = $wxResult['session_key']; //根据当前登录的用户获取手机号
                    $pc = new WXBizDataCrypt($appid, $session_key);
                    $errCode = $pc->decryptData($data['encryptedData'], $data['iv'], $data);
                    if ($errCode == 0) {
                        $phoneData = json_decode($data, true);
//                        $update_phone = [
//                          //  'mobile' => $phoneData['phoneNumber'],
//                            'openid' => $wxResult['openid'],
//                            'session_key' => $wxResult['session_key']
//                        ];
//                        $user->save($update_phone);
                        return $this->response(['phone'=>$phoneData]);
                    } else {
                        return $this->response($errCode, '获取手机号失败,请您手动输入');
                    }
                }
            }
        } else {
            return $this->response(500, '连接微信服务器失败');
        }
    }

    /**
     * @User: 刘海龙
     * @Date: 2021/9/3
     * @Time: 16:29
     * @return \think\response\Json
     * 发送短信
     */
    public function getSmsCode()
    {
        $EXPIRE_SEC = 900;    // 过期时间间隔
        $mobile = $this->request->param('mobile', '');
        // 获取验证码
        $code = $this->generate_code(4); //验证码
        $vcKey = 'zfhf_' . $mobile;
        $is_key = $this->redis->EXISTS($vcKey);
        if ($is_key === 0) {
            $res = $this->sendSms($mobile, $code);
            if ($res['result'] === 0) {
                $data = array('zfhf' => $code);
                $this->redis->set($vcKey, json_encode($data));
                $this->redis->expire($vcKey, $EXPIRE_SEC); // 设置验证码过期时间
            }
        } else {
            // 验证码重发限制
            $data = json_decode($this->redis->get($vcKey), true);
            $vc = $data['zfhf'];
            $res = $this->sendSms($mobile, $vc);
            if ($res['result'] === 0) {
                $ttl = $this->redis->ttl($vcKey);
                $this->redis->set($vcKey, json_encode($data));
                $this->redis->expire($vcKey, $ttl + $EXPIRE_SEC);
            }
        }
        return $this->response();
    }

    /**
     * @param $mobile
     * @param $vc
     * @User: 刘海龙
     * @Date: 2021/9/3
     * @Time: 16:29
     * @return mixed
     * 发送短信
     */
    public function sendSms($mobile, $vc)
    {
        $phoneNumbers = [$mobile];
        $AppId = Config::get('sms.AppId');
        $key = Config::get('sms.AppKey');
        $templateId = Config::get('sms.template');
        $smsSign = Config::get('sms.sign');
        $msender = new SmsMultiSender($AppId, $key);
        $params = [$vc, '15'];
        $result = $msender->sendWithParam("86", $phoneNumbers,
            $templateId, $params, $smsSign, "", "");  // 签名参数不能为空串
        $rsp = json_decode($result, true);
        return $rsp;
    }

    /**
     * @User: 刘海龙
     * @Date: 2021/9/3
     * @Time: 16:58
     * @return \think\response\Json
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     * 验证输入验证码是否正确
     */
    public function checkSmsCode()
    {
        $data = $this->request->param();
        $redis_key = 'zfhf_' . $data['mobile'];
        $is_key = $this->redis->EXISTS($redis_key);
        if ($is_key === 0) {
            return $this->response(403, '验证码不存在请重新获取');
        } else {
            $redis_data = json_decode($this->redis->get($redis_key), true);
            $vc = $redis_data['zfhf'];
            if ($vc != $data['code']) {
                return $this->response(403, '验证码输入有误,请重新输入');
            }
        }
        $user = Users::find($this->request->wx_user_id);
        if (is_null($user)) {
            return $this->response(403, '用户不存在');
        }
        $mobile = Users::where(['mobile'=> $data['mobile']])->find();
        if (!is_null($mobile)){
            $mobile->save([
                'nickname'=>$data['userInfo']['nickname'],
                'head_img'=>$data['userInfo']['head_img'],
                'openid'=>$data['userInfo']['openid'],
                'session_key'=>$data['userInfo']['session_key'],
                'is_auth'=>$data['userInfo']['is_auth'],
                'is_management'=>$data['userInfo']['is_management'],
                'unit_id'=>$data['userInfo']['unit_id'],
            ]);


            //重新生成token
            $key = $this->token->createToken($mobile['id']);//生成token
            $mobile['user_type'] = 1; //重新生成的
            $mobile['new_token'] = $key;
            //删除元数据
//            Users::destroy($data['userInfo']['id'],true); //删除原有的
            return $this->response($mobile);
        }else{
            //如果为空 或者 当前存在的手机号于获取验证码的手机号不一致的时候更新
            if (empty($user->mobile) || $user->mobile !== $data['mobile']) {
                $user->save([
                    'mobile' => $data['mobile']
                ]);
            }
            $mobile['user_type'] = 2; //新用户
            return $this->response($user);
        }
    }

    /**
     * @User: 刘海龙
     * @Date: 2021/9/8
     * @Time: 8:52
     * @return \think\response\Json
     * @throws \think\db\exception\DbException
     * 获取微信用户列表
     */
    public function wechatList(){
        $limit = $this->request->param('limit',10);
        $res = Users::with(['admins','unit'])->paginate($limit)->each(function ($item,$key){
            $item['auth_name'] = Users::$is_auth_type[$item['is_auth']];
            return $item;
        });
        return $this->response($res);
    }

    /**
     * @param $id
     * @User: 刘海龙
     * @Date: 2021/9/8
     * @Time: 9:15
     * @return \think\response\Json
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     * 删除微信用户
     */
    public function wechatDelete($id){
        $ids = explode(',', $id);
        foreach ($ids as $id) {
            if (intval($id) === 1) {
                return $this->response(403, '超级管理员,不能删除');
            }
            $user = Users::find($id);
            if (is_null($user)) {
                return $this->response(404, '此用户不存在');
            }
            //->force()
            $user->force()->delete();
        }
        return $this->response();
    }

    /**
     * @User: 刘海龙
     * @Date: 2021/9/8
     * @Time: 9:47
     * @return \think\response\Json
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     * 随机生成用户名及手机号
     */
    public function randomCreateAccount()
    {
        $res = EnterUnit::select();
        $new_arr = [];
        foreach ($res as $key => $v) {
            $new_arr[]['enter_unit_id'] = $v['id'];
            $new_arr[$key]['mobile'] = $this->randomMobile(1)[0];
            $new_arr[$key]['password'] = password_hash('111111',PASSWORD_DEFAULT);
            $new_arr[$key]['username'] = getname(1)[0];
            $new_arr[$key]['email'] = $this->randomMobile(1)[0].'@qq.com';
            $new_arr[$key]['remark'] = '随机生成账户,出品优质API';
            $new_arr[$key]['create_id'] = 1;
        }
        $admin = new Admins();
        $admin->saveAll($new_arr);
        return $this->response();
    }

    protected function randomMobile($n)
    {
        $tel_arr = SystemConfig::where(['name'=>'randomMobile'])->value('value');
        $tel_arr = explode(',',$tel_arr);
        $tmp = [];
        for($i = 0; $i < $n; $i++) {
            $tmp[] = $tel_arr[array_rand($tel_arr)].mt_rand(1000,9999).mt_rand(1000,9999);
            // $tmp[] = $tel_arr[array_rand($tel_arr)].'xxxx'.mt_rand(1000,9999);
        }
        return array_unique($tmp);
    }
}
